home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / intuitin / dmouse.1 < prev    next >
Text File  |  1988-10-22  |  23KB  |  902 lines

  1. Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!uflorida!gatech!bbn!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i008:  dmouse - mouse accelerator plus V1.10
  5. Message-ID: <9770@swan.ulowell.edu>
  6. Date: 22 Oct 88 04:22:15 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 891
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
  12. Posting-number: Volume 2, Issue 8
  13. Archive-name: intuition/dmouse.1
  14.  
  15. [Docs are with the binary, source hackers read the code.  :-)   ..Bob]
  16.  
  17. # This is a shell archive.  Remove anything before this line
  18. # then unpack it by saving it in a file and typing "sh file"
  19. # (Files unpacked will be owned by you and have default permissions).
  20. # This archive contains the following files:
  21. #    ./Makefile
  22. #    ./dmouse-handler.c
  23. #    ./dmouse.c
  24. #    ./dmouse.h
  25. #
  26. if `test ! -s ./Makefile`
  27. then
  28. echo "writing ./Makefile"
  29. cat > ./Makefile << '\Rogue\Monster\'
  30.  
  31. #   Makefile for DMouse
  32. #
  33. #   +L = 32 bit ints
  34.  
  35. SYMS=    include:symbols.m
  36. SYMC=    include:local/makesymbols.c
  37. CFLAGS= +L +I$(SYMS)
  38.  
  39. SR1 = dmouse.c
  40. SR2 = dmouse-handler.c
  41.  
  42. OB1 = ram:dmouse.o
  43. OB2 = ram:dmouse-handler.o
  44.  
  45. EX1 = c:dmouse
  46. EX2 = l:dmouse-handler
  47.  
  48.  
  49. all:    $(SYMS) $(EX1) $(EX2)
  50.  
  51. arc:
  52.     copy dmouse-handler.c ram:dmouse-h.c
  53.     copy l:dmouse-handler ram:dmouse-h
  54.     -delete ram:dm.arc
  55.     arc a ram:dm ram:dmouse-h.c ram:dmouse-h dmouse.doc dmouse.c c:dmouse execute.me
  56.     delete ram:dmouse-h.c ram:dmouse-h
  57.  
  58. $(EX1) : $(OB1)
  59.     ln +Q $(OB1) -lc32 -o $(EX1)
  60.  
  61. $(EX2) : $(OB2)
  62.     ln +Q $(OB2) -lc32 -ldres -o $(EX2)
  63.  
  64.  
  65. $(OB1) : $(SR1)
  66.     cc $(CFLAGS) $(SR1) -o $(OB1)
  67.  
  68. $(OB2) : $(SR2)
  69.     cc $(CFLAGS) $(SR2) -o $(OB2)
  70.  
  71. $(SYMS):    $(SYMC)
  72.     make -f include:local/Makefile
  73.  
  74. \Rogue\Monster\
  75. else
  76.   echo "will not over write ./Makefile"
  77. fi
  78. if [ `wc -c ./Makefile | awk '{printf $1}'` -ne 782 ]
  79. then
  80. echo `wc -c ./Makefile | awk '{print "Got " $1 ", Expected " 782}'`
  81. fi
  82. if `test ! -s ./dmouse-handler.c`
  83. then
  84. echo "writing ./dmouse-handler.c"
  85. cat > ./dmouse-handler.c << '\Rogue\Monster\'
  86.  
  87. /*
  88.  *  DMOUSE-HANDLER.C        compile 32 bit integers (+L), c32.lib
  89.  *                AZTEC COMPILATION
  90.  *  28 June 1988
  91.  *
  92.  *  Note on upping the handler process priority.  This is done to cause the
  93.  *  handler task to get CPU before the current input event completes its
  94.  *  processing so intuition calls made by the process are executed before
  95.  *  the event is propogated.  If said intuition calls block, it's ok
  96.  *  because they are not blocking the input handler process.
  97.  */
  98.  
  99. #include "dmouse.h"
  100.  
  101.  
  102. DMS    *Dms;
  103. IBASE    *IntuitionBase;
  104. GFXBASE *GfxBase;
  105. long    *LayersBase;
  106. long    *DResBase;
  107.  
  108. static PORT    *IPCPort = NULL;
  109.  
  110. static char    STimedout = 0;
  111. static char    MTimedout = 0;
  112. static long    STime = 0, MTime = 0;
  113.  
  114.  
  115. #define IBASE IntuitionBase
  116.  
  117. NS    Ns = {    0, 0, 64, -1, 1, -1, -1, 0, CUSTOMSCREEN|SCREENQUIET };
  118. IE DummyIE = { 0 };
  119.  
  120. IE *handler();
  121.  
  122. short    NRMe;    /*  Don't Repeat Mouse Events   */
  123.  
  124. _main()
  125. {
  126.     register DMS *dms;
  127.     IOR  *ior;
  128.     INT addhand;
  129.  
  130.     {
  131.     register PROC *proc = (PROC *)FindTask(NULL);
  132.     proc->pr_ConsoleTask = NULL;
  133.     }
  134.     NRMe = 0;
  135.     dms = Dms = (DMS *)FindPort(PORTNAME);
  136.     if (!dms)
  137.     _exit(0);
  138.     dms->Port.mp_Flags = PA_SIGNAL;
  139.     dms->Port.mp_SigBit = AllocSignal(-1);
  140.     dms->Port.mp_SigTask = FindTask(NULL);
  141.     dms->HandTask = dms->Port.mp_SigTask;
  142.     ior = CreateStdIO(&dms->Port);
  143.     IntuitionBase = OpenLibrary("intuition.library", 0);
  144.     GfxBase = OpenLibrary("graphics.library", 0);
  145.     LayersBase = OpenLibrary("layers.library", 0);
  146.     DResBase = OpenLibrary("dres.library", 0);      /*  not required    */
  147.  
  148.     if (!IntuitionBase || !GfxBase || !LayersBase)
  149.     goto startupfail;
  150.     addhand.is_Node.ln_Pri = dms->IPri;
  151.     addhand.is_Code = (FPTR)handler;
  152.     addhand.is_Data = NULL;
  153.  
  154.     if (OpenDevice("input.device", 0, ior, 0)) {
  155.     goto startupfail;
  156.     } else {
  157.     SCR *scr = NULL;
  158.     uword *SprSavePtr = NULL;
  159.     long ipc_mask = 0;
  160.  
  161.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  162.     ior->io_Command = IND_ADDHANDLER;
  163.     ior->io_Data = (APTR)&addhand;
  164.     ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  165.     DoIO(ior);
  166.  
  167.     if (DResBase) {
  168.         if (IPCPort = OpenIPC("dmouse.CMD", 0))
  169.         ipc_mask = 1 << IPCPort->mp_SigBit;
  170.     }
  171.     for (;;) {
  172.         register long sigs = Wait(SBF_C|(1<<dms->Port.mp_SigBit)|ipc_mask);
  173.         if (sigs & (1 << dms->Port.mp_SigBit)) {
  174.         register REQ *msg;
  175.         while (msg = GetMsg(&dms->Port)) {
  176.             switch((long)msg->Msg.mn_Node.ln_Name) {
  177.             case REQ_SCREENON:
  178.             if (scr)
  179.                 CloseScreen(scr);
  180.             scr = NULL;
  181.             break;
  182.             case REQ_SCREENOFF:
  183.             if (scr) {
  184.                 ScreenToFront(scr);
  185.             } else {
  186.                 if (scr = OpenScreen(&Ns))
  187.                 SetRGB4(&scr->ViewPort, 0, 0, 0, 0);
  188.             }
  189.             break;
  190.             case REQ_MOUSEON:
  191.             if (SprSavePtr) {
  192.                 register COPINIT *ci = GfxBase->copinit;
  193.                 ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
  194.                 ci->sprstrtup[3] = (uword)(long)SprSavePtr;
  195.                 SprSavePtr = NULL;
  196.             }
  197.             break;
  198.             case REQ_MOUSEOFF:
  199.             {
  200.                 register COPINIT *ci = GfxBase->copinit;
  201.                 if (!SprSavePtr)
  202.                 SprSavePtr = (uword *)((ci->sprstrtup[1] << 16) | ci->sprstrtup[3]);
  203.                 ci->sprstrtup[1] = (ulong)dms->NoSprData >> 16;
  204.                 ci->sprstrtup[3] = (uword)(long)dms->NoSprData;
  205.             }
  206.             break;
  207.             case REQ_DOCMD:
  208.             {
  209.                 long fh = Open("nil:", 1006);
  210.                 Execute(dms->Cmd, NULL, fh);
  211.                 if (fh)
  212.                 Close(fh);
  213.             }
  214.             break;
  215.             case REQ_RAWMOUSE:
  216.             {
  217.                 register LAYER *layer;
  218.  
  219.                 NRMe = 0;
  220.                 Forbid();
  221.                 layer = WhichMouseLayer();
  222.                 if (msg->ie_Code == IECODE_RBUTTON && dms->LMBEnable && (msg->ie_Qualifier & dms->RQual)) {
  223.                 register WIN *win;
  224.                 if (layer && (win = (WIN *)layer->Window) && !(win->Flags & BACKDROP) && (win->NextWindow || win->WScreen->FirstWindow != win)) {
  225.                     if (dms->Workbench)
  226.                     WindowToBack(win);
  227.                     else
  228.                     BehindLayer(0, layer);
  229.                 } else if (IBASE->FirstScreen)
  230.                     ScreenToBack(IBASE->FirstScreen);
  231.                 }
  232.                 if (layer && layer->Window) {
  233.                 if (msg->ie_Code == IECODE_LBUTTON && !(((WIN *)layer->Window)->Flags & BACKDROP) && dms->LMBEnable && layer->ClipRect && layer->ClipRect->Next) {
  234.                     /*
  235.                      *    Note: Case where it is the 'first' click in a series, where dms->CTime is
  236.                      *          garbage, works properly no matter what DoubleClick returns.
  237.                      */
  238.                     if (dms->LQual == 0 || (msg->ie_Qualifier & dms->LQual)) {
  239.                     if ((APTR)dms->CWin == layer->Window && DoubleClick(dms->CTime.tv_secs, dms->CTime.tv_micro, msg->ie_TimeStamp.tv_secs, msg->ie_TimeStamp.tv_micro))
  240.                         --dms->CLeft;
  241.                     else
  242.                         dms->CLeft = dms->Clicks - 1;
  243.                     dms->CTime = msg->ie_TimeStamp;
  244.                     dms->CWin = (WIN *)layer->Window;
  245.                     if (dms->CLeft == 0) {
  246.                         dms->CLeft = dms->Clicks;
  247.                         if (dms->Workbench)
  248.                         WindowToFront(layer->Window);
  249.                         else
  250.                         UpfrontLayer(0, layer);
  251.                     }
  252.                     }
  253.                 }
  254.                 if ((dms->AAEnable & 1) && layer->Window != IBASE->ActiveWindow && msg->ie_Code == IECODE_NOBUTTON && !(msg->ie_Qualifier & 0x7000)) {
  255.                     if (!IBASE->ActiveWindow || !IBASE->ActiveWindow->FirstRequest)
  256.                     ActivateWindow(layer->Window);
  257.                 }
  258.                 }
  259.                 Permit();
  260.             }
  261.             break;
  262.             case REQ_RAWKEY:
  263.             {
  264.                 register LAYER *layer;
  265.  
  266.                 Forbid();
  267.                 layer = WhichMouseLayer();
  268.                 if (layer && layer->Window && layer->Window != IBASE->ActiveWindow) {
  269.                 if (!IBASE->ActiveWindow || !IBASE->ActiveWindow->FirstRequest)
  270.                     ActivateWindow(layer->Window);
  271.                 }
  272.                 Permit();
  273.             }
  274.             break;
  275.             }
  276.             FreeMem(msg, msg->Msg.mn_Length);
  277.         }
  278.         }
  279.         if (sigs & SBF_C)
  280.         break;
  281.         if (sigs & ipc_mask) {
  282.         register IPCMSG *msg;
  283.         register char *ptr;
  284.         long req;
  285.         while (msg = GetMsg(IPCPort)) {
  286.             req = 0;
  287.             if (ptr = (char *)msg->TBuf) {
  288.             while (*ptr++);
  289.             if (strcmp(ptr, "blank") == 0) {
  290.                 req = REQ_SCREENOFF;
  291.                 STimedout = 1;
  292.             }
  293.             if (strcmp(ptr, "noblank") == 0)
  294.                 req = REQ_SCREENON;
  295.             if (strcmp(ptr, "mouse") == 0)
  296.                 req = REQ_MOUSEON;
  297.             if (strcmp(ptr, "nomouse") == 0) {
  298.                 MTimedout = 1;
  299.                 req = REQ_MOUSEOFF;
  300.             }
  301.             }
  302.             if (req)
  303.             sendrequest(req, NULL);
  304.             ReplyIPC(msg, NULL, 0, ((req)?0:IF_NOTFND));
  305.         }
  306.         }
  307.     }
  308.     ior->io_Command = IND_REMHANDLER;
  309.     ior->io_Data = (APTR)&addhand;
  310.     ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  311.     DoIO(ior);
  312.     ior->io_Command = IND_WRITEEVENT;    /*  NULL EVENT    */
  313.     ior->io_Length = sizeof(IE);
  314.     ior->io_Data = (APTR)&DummyIE;
  315.     ior->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  316.     DoIO(ior);
  317.     CloseDevice(ior);
  318.     {
  319.         register MSG *msg;
  320.         while (msg = GetMsg(&dms->Port))
  321.         FreeMem(msg, msg->mn_Length);
  322.     }
  323.     if (scr)
  324.         CloseScreen(scr);
  325.     if (SprSavePtr) {
  326.         register COPINIT *ci = GfxBase->copinit;
  327.         ci->sprstrtup[1] = (ulong)SprSavePtr >> 16;
  328.         ci->sprstrtup[3] = (uword)(long)SprSavePtr;
  329.         SprSavePtr = NULL;
  330.     }
  331.     }
  332.     goto closedown;
  333. startupfail:
  334.     dms->StartupError = 1;
  335.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  336.     Wait(SBF_C);
  337. closedown:
  338.     DeleteStdIO(ior);
  339. fail:
  340.     if (IPCPort)
  341.     CloseIPC(IPCPort);
  342.     if (DResBase)
  343.     CloseLibrary(DResBase);
  344.     if (IntuitionBase)
  345.     CloseLibrary(IntuitionBase);
  346.     if (GfxBase)
  347.     CloseLibrary(GfxBase);
  348.     if (LayersBase)
  349.     CloseLibrary(LayersBase);
  350.     Forbid();
  351.     Signal(dms->ShakeTask, 1 << dms->ShakeSig);
  352. }
  353.  
  354.  
  355. #asm
  356.         ;    A0 = pointer to event linked list
  357.         ;    A1 = pointer to my data segment
  358.         ;    return new event linked list in D0
  359.  
  360.         public  _CHandler
  361.  
  362. _handler:
  363.         movem.l D2/D3/A0/A1/A4/A6,-(sp)
  364.         jsr     _CHandler
  365.         movem.l (sp)+,D2/D3/A0/A1/A4/A6
  366.         rts
  367.  
  368. #endasm
  369.  
  370. /*
  371.  *  (1) Accellerate mouse movements.
  372.  *  (2) Auto-Select window
  373.  */
  374.  
  375. IE *
  376. CHandler(scr0, scr1, Ev)
  377. IE *Ev;
  378. {
  379.     register IE *ev;
  380.     register DMS *dms;
  381.  
  382.     geta4();
  383.     dms = Dms;
  384.     for (ev = Ev; ev; ev = Ev->ie_NextEvent) {
  385.     switch(ev->ie_Class) {
  386.     case IECLASS_RAWMOUSE:
  387.         /*
  388.          *    Mouse events restore both the screen and mouse pointer.
  389.          */
  390.  
  391.         STime = ev->ie_TimeStamp.tv_secs + dms->STo;
  392.         MTime = ev->ie_TimeStamp.tv_secs + dms->MTo;
  393.         if (STimedout)
  394.         sendrequest(REQ_SCREENON, ev);
  395.         if (MTimedout)
  396.         sendrequest(REQ_MOUSEON, ev);
  397.         STimedout = MTimedout = 0;
  398.  
  399.         /*
  400.          *    Mouse Acceleration
  401.          */
  402.         {
  403.         register short n;
  404.         register short s;
  405.  
  406.         if (dms->Acc != 1) {
  407.             n = ev->ie_X;
  408.             s = 1;
  409.             if (n < 0) {
  410.             n = -n;
  411.             s = -1;
  412.             }
  413.             if (n > dms->AThresh)
  414.             ev->ie_X = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
  415.             n = ev->ie_Y;
  416.             s = 1;
  417.             if (n < 0) {
  418.             n = -n;
  419.             s = -1;
  420.             }
  421.             if (n > dms->AThresh)
  422.             ev->ie_Y = s * (short)((n - dms->AThresh - 1) * dms->Acc + dms->AThresh + 1);
  423.         }
  424.         }
  425.  
  426.         /*
  427.          *    Auto Activate and LMB (win/scrn front/bak)
  428.          */
  429.  
  430.         if (dms->LMBEnable && ev->ie_Code == IECODE_RBUTTON && (ev->ie_Qualifier & dms->RQual))
  431.         ev->ie_Class = IECLASS_NULL;    /*  remove event    */
  432.         if (NRMe == 0 && ((dms->AAEnable & 1) || dms->LMBEnable)) {
  433.         register short old;
  434.         NRMe = 1;
  435.         if (ev->ie_Code != IECODE_NOBUTTON)
  436.             old = SetTaskPri(dms->Port.mp_SigTask, 21);
  437.         sendrequest(REQ_RAWMOUSE, ev);
  438.         if (ev->ie_Code != IECODE_NOBUTTON)
  439.             SetTaskPri(dms->Port.mp_SigTask, old);
  440.         }
  441.         break;
  442.     case IECLASS_RAWKEY:
  443.         /*
  444.          *    Keyboard events will kill the screen timeout but not
  445.          *    the mouse timeout.  Note that the priority of the
  446.          *    co-process must be upped to ensure it is able to make the
  447.          *    window active before the keystroke is passed further.
  448.          *
  449.          *    key releases are ignored
  450.          */
  451.         if (ev->ie_Code & 0x80)
  452.         break;
  453.         if (dms->AAEnable & 2) {
  454.         register short old = SetTaskPri(dms->Port.mp_SigTask, 21);
  455.         sendrequest(REQ_RAWKEY, ev);
  456.         SetTaskPri(dms->Port.mp_SigTask, old);
  457.         }
  458.         STime = ev->ie_TimeStamp.tv_secs + dms->STo;
  459.         if (STimedout) {
  460.         sendrequest(REQ_SCREENON, ev);
  461.         if (dms->MTo == 0)
  462.             sendrequest(REQ_MOUSEON, ev);
  463.         }
  464.         STimedout = 0;
  465.         if (ev->ie_Code == dms->Code && ev->ie_Qualifier == dms->Qual) {
  466.         sendrequest(REQ_DOCMD, ev);
  467.         ev->ie_Class = IECLASS_NULL;    /*  remove event    */
  468.         }
  469.         break;
  470.     case IECLASS_TIMER:
  471.         /*
  472.          *    On a timer event, if timeout has occured execute the operation
  473.          *    and reset the timeout.    Note that this will cause continuous
  474.          *    timeouts every STo and MTo seconds... required because at any
  475.          *    time Intuition might turn the mouse back on or open a screen or
  476.          *    something and I want the blanker's to work in the long run.
  477.          */
  478.         {
  479.         register long old;
  480.         if (dms->Reset) {
  481.             dms->Reset = 0;
  482.             STime = ev->ie_TimeStamp.tv_secs + dms->STo;
  483.             MTime = ev->ie_TimeStamp.tv_secs + dms->MTo;
  484.         }
  485.         if (dms->STo && (old = STime - ev->ie_TimeStamp.tv_secs) < 0) {
  486.             STime = ev->ie_TimeStamp.tv_secs + dms->STo + 10;
  487.             STimedout = 1;
  488.             MTimedout = 1;
  489.             if (old > -10) {
  490.             sendrequest(REQ_SCREENOFF, ev);
  491.             sendrequest(REQ_MOUSEOFF, ev);
  492.             }
  493.         }
  494.         if (dms->MTo && (old = MTime - ev->ie_TimeStamp.tv_secs) < 0) {
  495.             MTime = ev->ie_TimeStamp.tv_secs + dms->MTo + 1;
  496.             MTimedout = 1;
  497.             if (old > -10)
  498.             sendrequest(REQ_MOUSEOFF, ev);
  499.         }
  500.         }
  501.         break;
  502.     }
  503.     }
  504.     return(Ev);
  505. }
  506.  
  507. sendrequest(creq, ev)
  508. long creq;
  509. register IE *ev;
  510. {
  511.     register REQ *req = AllocMem(sizeof(REQ), MEMF_PUBLIC);
  512.  
  513.     if (req) {
  514.     req->Msg.mn_Node.ln_Name = (char *)creq;
  515.     req->Msg.mn_ReplyPort = NULL;
  516.     req->Msg.mn_Length = sizeof(REQ);
  517.     if (ev) {
  518.         req->ie_Code = ev->ie_Code;
  519.         req->ie_Qualifier = ev->ie_Qualifier;
  520.         req->ie_TimeStamp = ev->ie_TimeStamp;
  521.     }
  522.     PutMsg(&Dms->Port, req);
  523.     }
  524. }
  525.  
  526. LAYER *
  527. WhichMouseLayer()
  528. {
  529.     register struct IntuitionBase *ib = IBASE;
  530.     register LAYER *layer = NULL;
  531.     register SCR *scr = ib->FirstScreen;
  532.  
  533.     for (scr = ib->FirstScreen; scr; scr = scr->NextScreen) {
  534.     register short mousey = ib->MouseY;
  535.     register short mousex = ib->MouseX;
  536.     if (!(scr->ViewPort.Modes & LACE))
  537.         mousey >>= 1;
  538.     if (!(scr->ViewPort.Modes & HIRES))
  539.         mousex >>= 1;
  540.     if (layer = WhichLayer(&scr->LayerInfo, mousex, mousey - scr->ViewPort.DyOffset))
  541.         break;
  542.     if (mousey >= scr->ViewPort.DyOffset)
  543.         break;
  544.     }
  545.     return(layer);
  546. }
  547.  
  548.  
  549. \Rogue\Monster\
  550. else
  551.   echo "will not over write ./dmouse-handler.c"
  552. fi
  553. if [ `wc -c ./dmouse-handler.c | awk '{printf $1}'` -ne 12127 ]
  554. then
  555. echo `wc -c ./dmouse-handler.c | awk '{print "Got " $1 ", Expected " 12127}'`
  556. fi
  557. if `test ! -s ./dmouse.c`
  558. then
  559. echo "writing ./dmouse.c"
  560. cat > ./dmouse.c << '\Rogue\Monster\'
  561.  
  562. /*
  563.  *  DMOUSE.C    V1.10  31 July 1988    (Aztec Compile, +L  ... 32 bit ints)
  564.  *                     and link w/ c32.lib
  565.  *
  566.  *  DMOUSE QUIT
  567.  *  DMOUSE -a# -t# -s# -m# -c# -p# -w# -Ln -lqqqq -Rqqqq -An -Kcccc -Qqqqq -C cmd
  568.  *
  569.  *  -a#     # = acceleration, default 3.    1 to disable
  570.  *  -t#     # = mouse threshold before acceleration takes effect, def. 0
  571.  *        (in pixels/event)
  572.  *  -s#     # = screen timeout, default 5min,    0 to disable
  573.  *  -m#     # = pointer timeout, default 5 secs,0 to disable
  574.  *  -c#     # = # of clicks to bring window to front
  575.  *  -p#     # = input device priority
  576.  *  -w#     1 = Use WindowToFront()/WindowToBack()  else    (workbench users)
  577.  *        0 = Use UpFrontLayer(), etc...                  (cli users)
  578.  *  -L0     Disable LeftMouseButton->WindowToFront (LMB+RMB->ToBack)
  579.  *  -L1     Enable it
  580.  *  -lqqqq  Set qualifier + LMB for Window to front (default none)
  581.  *  -Rqqqq  Set qualifier + RMB for Window/ScreenToBack (default LMB)
  582.  *  -A0     Disable Auto-Activate window on mouse move
  583.  *  -A1     Enable it, keyhit-auto-activate disabled    (bit 0 = mouse aa)
  584.  *  -A3     Enable it, keyhit-auto-activate enabled    (bit 1 = key aa)
  585.  *  -Kcccc  Set key code in hex that activates cmd, def is escape
  586.  *  -Qqqqq  Set key qualifier in hex for keycode, def is left-amiga
  587.  *  -C cmd  Set command (must be last option on command line), def NewCli
  588.  */
  589.  
  590. #include <stdio.h>
  591. #include "dmouse.h"
  592.  
  593. #define VERSION 10
  594.  
  595. int    Enable_Abort;        /*    CLI break enable    */
  596.  
  597. main(ac, av)
  598. char *av[];
  599. {
  600.     register short i, j, len;
  601.     register long val;
  602.     register char *ptr;
  603.     register DMS  *dms = (DMS *)FindPort(PORTNAME);
  604.     short   exists = (dms != NULL);
  605.     short   create = (dms == NULL);
  606.     short   quit = 0;
  607.  
  608.     Enable_Abort = 0;
  609.     if (create) {
  610.     dms = AllocMem(sizeof(DMS), MEMF_PUBLIC|MEMF_CLEAR);
  611.     dms->IPri = 51;
  612.     dms->Version = VERSION;
  613.     dms->Acc = 3;
  614.     dms->STo = 5*60;
  615.     dms->MTo = 5;
  616.     dms->Code = 0x45;
  617.     dms->Qual = 0x8040;
  618.     dms->RQual= 0x4000;
  619.     dms->Clicks = 1;
  620.     dms->CLeft = dms->Clicks;
  621.     strcpy(dms->Cmd, "newcli");
  622.     dms->LMBEnable = 1;
  623.     dms->AAEnable = 3;
  624.     dms->NoSprData = AllocMem(12, MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR);
  625.     dms->NoSprData[0] = 0xFE00;
  626.     dms->NoSprData[1] = 0xFF00;
  627.     }
  628.  
  629.     for (i = 1; i < ac; ++i) {
  630.     ptr = av[i];
  631.     if (strcmp(ptr, "QUIT") == 0 || strcmp(ptr, "quit") == 0) {
  632.         quit = 1;
  633.         create = 0;
  634.         break;
  635.     }
  636.     val = atoi(ptr+2);
  637.     if (*ptr != '-')
  638.         goto def;
  639.  
  640.     switch(ptr[1]) {
  641.     case 'a':
  642.         dms->Acc = val;
  643.         break;
  644.     case 'c':
  645.         if (val < 1)
  646.         val = 1;
  647.         dms->Clicks = dms->CLeft = val;
  648.         break;
  649.     case 'w':
  650.         dms->Workbench = val;
  651.         break;
  652.     case 'p':
  653.         dms->IPri = val;
  654.         break;
  655.     case 't':
  656.         dms->AThresh = val;
  657.         break;
  658.     case 's':
  659.         dms->STo = val;
  660.         break;
  661.     case 'm':
  662.         dms->MTo = val;
  663.         break;
  664.     case 'L':
  665.         dms->LMBEnable = val;
  666.         break;
  667.     case 'l':
  668.         dms->LQual = ahtoi(ptr+2);
  669.         break;
  670.     case 'R':
  671.         dms->RQual = ahtoi(ptr+2);
  672.         break;
  673.     case 'A':
  674.         dms->AAEnable = val;
  675.         break;
  676.     case 'K':
  677.         dms->Code = ahtoi(ptr+2);
  678.         break;
  679.     case 'Q':
  680.         dms->Qual = ahtoi(ptr+2) | 0x8000;
  681.         break;
  682.     case 'C':
  683.         for (len = strlen(ptr+2) + 2, j = i + 1; j < ac; ++j)
  684.         len += strlen(av[j]) + 1;
  685.         strcpy(dms->Cmd, ptr + 2);
  686.         for (j = i + 1; j < ac; ++j) {
  687.         if (dms->Cmd[0])
  688.             strcat(dms->Cmd, " ");
  689.         strcat(dms->Cmd, av[j]);
  690.         }
  691.         i = ac;
  692.         break;
  693.     default:    def:
  694.         puts("DMOUSE QUIT  or");
  695.         puts("DMOUSE -a# -t# -s# -m# -Ln -Rqqqq -An -Kcccc -Qqqqq -C cmd");
  696.         printf("V1.%02d PUBLIC DOMAIN, Matthew Dillon, 28 June 1988\n\n", VERSION);
  697.         puts("  -a#     Acceleration (default 3)");
  698.         puts("  -t#     Accel. threshold (default 0)");
  699.         puts("  -s#     Screen timeout (default 300)");
  700.         puts("  -m#     Mouse timeout (default 5)");
  701.         puts("  -c#     Set # of clicks for wintofront (default 1)");
  702.         puts("  -p#     # = input device priority");
  703.         puts("  -w#     0 = use UpFrontLayer().. 1 = use WindowToFront()");
  704.         puts("  -L0/1   LMB disable/enable (default 1=enabled)");
  705.         puts("  -lqqqq  LMB qualifier wintofront (default 0=none)");
  706.         puts("  -Rqqqq  RMB qualifier wintoback (default 4000=LMB)");
  707.         puts("  -A0-3   Auto-Activate Window disable/enable. B0=mouse B1=keyboard");
  708.         puts("  -Kcccc  Command Key Code, default 45 = esc");
  709.         puts("  -Qqqqq  Command Key Qualifier, default 40 = Left Amiga");
  710.         puts("  -C cmd  cmd to run, must be last option");
  711.         puts("Note: LMB(or -R qualifier)(hold)+RMB = WindowToBack");
  712.         puts("\n");
  713.         puts("Additionaly, Most options may be modified while DMOUSE is active");
  714.         create = 0;
  715.         i = ac;
  716.         break;
  717.     }
  718.     }
  719.     dms->Reset = 1;
  720.     if (!exists && create) {
  721.     PROC *proc;
  722.     printf("Installing DMouse, ");
  723.     fflush(stdout);
  724.     dms->Port.mp_Flags = PA_IGNORE;
  725.     dms->Port.mp_Node.ln_Pri = 0;
  726.     dms->Port.mp_Node.ln_Type= NT_MSGPORT;
  727.     dms->Port.mp_Node.ln_Name= AllocMem(sizeof(PORTNAME), MEMF_PUBLIC);
  728.     strcpy(dms->Port.mp_Node.ln_Name, PORTNAME);
  729.     NewList(&dms->Port.mp_MsgList);
  730.     dms->Segment = LoadSeg("l:DMouse-Handler");
  731.     if (!dms->Segment)
  732.         dms->Segment = LoadSeg("DMouse-Handler");
  733.     if (!dms->Segment) {
  734.         puts("Unable to find L:DMouse-Handler");
  735.         FreeMem(dms->Port.mp_Node.ln_Name, sizeof(PORTNAME));
  736.         create = 0;
  737.     } else {
  738.         AddPort(&dms->Port);
  739.         dms->ShakeTask = FindTask(NULL);
  740.         dms->ShakeSig = AllocSignal(-1);
  741.         proc = CreateProc(dms->Port.mp_Node.ln_Name, 1, dms->Segment, 4096);
  742.         Wait(1 << dms->ShakeSig);
  743.         FreeSignal(dms->ShakeSig);
  744.         exists = 1;
  745.         quit = dms->StartupError;
  746.         if (quit)
  747.         puts("Handler error");
  748.         else
  749.         printf("ok.  DMouse V1.%02d, by Matthew Dillon.  PUBLIC DOMAIN.\n", VERSION);
  750.     }
  751.     }
  752.     if (quit) {
  753.     if (exists) {
  754.         printf("Removing, ");
  755.         fflush(stdout);
  756.         dms->ShakeTask = FindTask(NULL);
  757.         dms->ShakeSig = AllocSignal(-1);
  758.         Signal(dms->HandTask, SBF_C);
  759.         Wait(1 << dms->ShakeSig);
  760.         FreeSignal(dms->ShakeSig);
  761.         RemPort(&dms->Port);
  762.         FreeMem(dms->Port.mp_Node.ln_Name, sizeof(PORTNAME));
  763.         UnLoadSeg(dms->Segment);
  764.         puts("ok");
  765.     }
  766.     exists = 0;
  767.     create = 0;
  768.     }
  769.     if (!exists) {
  770.     FreeMem(dms->NoSprData, 12);
  771.     FreeMem(dms, sizeof(DMS));
  772.     }
  773. }
  774.  
  775. ahtoi(str)
  776. register char *str;
  777. {
  778.     register long val = 0;
  779.     register char c;
  780.     while (c = *str) {
  781.     val <<= 4;
  782.     if (c >= '0' && c <= '9')
  783.         val |= (c & 15);
  784.     else
  785.         val |= (c & 15) + 9;
  786.     ++str;
  787.     }
  788.     return(val);
  789. }
  790.  
  791.  
  792. \Rogue\Monster\
  793. else
  794.   echo "will not over write ./dmouse.c"
  795. fi
  796. if [ `wc -c ./dmouse.c | awk '{printf $1}'` -ne 6451 ]
  797. then
  798. echo `wc -c ./dmouse.c | awk '{print "Got " $1 ", Expected " 6451}'`
  799. fi
  800. if `test ! -s ./dmouse.h`
  801. then
  802. echo "writing ./dmouse.h"
  803. cat > ./dmouse.h << '\Rogue\Monster\'
  804.  
  805. /*
  806.  *  DMOUSE.H
  807.  */
  808.  
  809. #include <local/typedefs.h>
  810. #include <local/ipc.h>
  811.  
  812. #define DMS struct _DMS
  813. #define REQ struct _REQ
  814.  
  815. #define PORTNAME    "DMouse"
  816.  
  817. #define REQ_SCREENON    -1
  818. #define REQ_SCREENOFF    -2
  819. #define REQ_MOUSEON    -3
  820. #define REQ_MOUSEOFF    -4
  821. #define REQ_DOCMD    -5
  822. #define REQ_RAWMOUSE    -6
  823. #define REQ_RAWKEY    -7
  824.  
  825. #define SBF_C    SIGBREAKF_CTRL_C
  826. #define SBF_D    SIGBREAKF_CTRL_D
  827. #define SBF_E    SIGBREAKF_CTRL_E
  828. #define SBF_F    SIGBREAKF_CTRL_F
  829.  
  830. typedef struct IOStdReq     IOR;
  831. typedef struct Interrupt    INT;
  832. typedef struct timeval        TS;
  833. typedef void            (*FPTR)();
  834.  
  835.  
  836. DMS {
  837.     PORT    Port;
  838.     short   Version;
  839.     short   Acc;
  840.     short   AThresh;
  841.     long    STo;
  842.     long    MTo;
  843.     uword   Code;
  844.     uword   Qual;
  845.     uword   RQual;        /*    Right button qualifier    */
  846.     uword   LQual;        /*    Left button qualifier    */
  847.     char    Cmd[256];
  848.     char    LMBEnable;
  849.     char    AAEnable;
  850.     char    IPri;
  851.     char    FSEnable;        /*    Foreign Screen Enable    */
  852.     char    Workbench;        /*    Use WindowToFront/Back    */
  853.     char    Reserved2;
  854.     char    Reserved3;
  855.     TASK    *HandTask;
  856.     TASK    *ShakeTask;
  857.     short   ShakeSig;
  858.     short   StartupError;
  859.     uword   *NoSprData;
  860.     long    Segment;
  861.  
  862.     uword   Clicks;    /*  # clicks required        */
  863.     uword   CLeft;    /*  # clicks left to do     */
  864.     TS        CTime;    /*  time of last click        */
  865.     WIN     *CWin;    /*  All clicks in same window    */
  866.     char    Reset;    /*  Option modified, reset tos    */
  867. };
  868.  
  869. REQ {
  870.     MSG     Msg;
  871.     TS        ie_TimeStamp;
  872.     uword   ie_Code;
  873.     uword   ie_Qualifier;
  874. };
  875.  
  876. extern IOR *CreateStdIO();
  877. extern SCR *OpenScreen();
  878. extern void *AllocMem();
  879. extern void *malloc();
  880. extern void *GetMsg();
  881. extern void *OpenLibrary();
  882. extern PORT *CreatePort();
  883. extern PROC *CreateProc();
  884. extern LAYER *WhichMouseLayer();
  885. extern LAYER *WhichLayer();
  886.  
  887.  
  888. \Rogue\Monster\
  889. else
  890.   echo "will not over write ./dmouse.h"
  891. fi
  892. if [ `wc -c ./dmouse.h | awk '{printf $1}'` -ne 1823 ]
  893. then
  894. echo `wc -c ./dmouse.h | awk '{print "Got " $1 ", Expected " 1823}'`
  895. fi
  896. echo "Finished archive 1 of 1"
  897. # if you want to concatenate archives, remove anything after this line
  898. exit
  899. -- 
  900. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  901. Have five nice days.
  902.